#include "NormalDistributionsTransformModel.h"

#include "core/AppDirectory.h"

namespace {
const QString UserFilename = "pcl.normal_distributions_transform_model.json";
}

NormalDistributionsTransformModel::NormalDistributionsTransformModel()
    : BasePclModel()
{
    setPclHelpPage("https://pcl.readthedocs.io/projects/tutorials/en/master/normal_distributions_transform.html");
}

NormalDistributionsTransformModel& NormalDistributionsTransformModel::get()
{
    static NormalDistributionsTransformModel instance;
    if (instance.filename().isEmpty()) {
        instance.setFilename(AppDirectory::get().getAppDocFile(UserFilename));
        instance.load();
    }
    return instance;
}

void NormalDistributionsTransformModel::fromJson(const QJsonObject& json, QStringList& errorList)
{
    BasePclModel::fromJson(json, errorList);

    pcdFile_ = json["pcdFile"].toString(pcdFile_);
    pcdFile2_ = json["pcdFile2"].toString(pcdFile2_);
    voxelGridLeafSizeX_ = json["voxelGridLeafSizeX"].toDouble(voxelGridLeafSizeX_);
    voxelGridLeafSizeY_ = json["voxelGridLeafSizeY"].toDouble(voxelGridLeafSizeY_);
    voxelGridLeafSizeZ_ = json["voxelGridLeafSizeZ"].toDouble(voxelGridLeafSizeZ_);

    ndtTransformationEpsilon_ = json["ndtTransformationEpsilon"].toDouble(ndtTransformationEpsilon_);
    ndtStepSize_ = json["ndtStepSize"].toDouble(ndtStepSize_);
    ndtResolution_ = json["ndtResolution"].toDouble(ndtResolution_);
    ndtMaxIterations_ = json["ndtMaxIterations"].toInt(ndtMaxIterations_);

    eigenRotation_ = json["eigenRotation"].toDouble(eigenRotation_);
    eigenTranslationX_ = json["eigenTranslationX"].toDouble(eigenTranslationX_);
    eigenTranslationY_ = json["eigenTranslationY"].toDouble(eigenTranslationY_);
    eigenTranslationZ_ = json["eigenTranslationZ"].toDouble(eigenTranslationZ_);

    targetPointSize_ = json["targetPointSize"].toInt(targetPointSize_);
    targetPointColor_ = QColor(json["targetPointColor"].toString(targetPointColor_.name()));
    outputPointSize_ = json["outputPointSize"].toInt(outputPointSize_);
    outputPointColor_ = QColor(json["outputPointColor"].toString(outputPointColor_.name()));

    resultHasConverged_ = json["resultHasConverged"].toBool(resultHasConverged_);
    resultFitnessScore_ = json["resultFitnessScore"].toDouble(resultFitnessScore_);
}

QJsonObject NormalDistributionsTransformModel::toJson() const
{
    QJsonObject json = BasePclModel::toJson();

    json.insert("pcdFile", QJsonValue(pcdFile_));
    json.insert("pcdFile2", QJsonValue(pcdFile2_));
    json.insert("voxelGridLeafSizeX", QJsonValue(voxelGridLeafSizeX_));
    json.insert("voxelGridLeafSizeY", QJsonValue(voxelGridLeafSizeY_));
    json.insert("voxelGridLeafSizeZ", QJsonValue(voxelGridLeafSizeZ_));

    json.insert("ndtTransformationEpsilon", QJsonValue(ndtTransformationEpsilon_));
    json.insert("ndtStepSize", QJsonValue(ndtStepSize_));
    json.insert("ndtResolution", QJsonValue(ndtResolution_));
    json.insert("ndtMaxIterations", QJsonValue(ndtMaxIterations_));
    json.insert("eigenRotation", QJsonValue(eigenRotation_));
    json.insert("eigenTranslationX", QJsonValue(eigenTranslationX_));
    json.insert("eigenTranslationY", QJsonValue(eigenTranslationY_));
    json.insert("eigenTranslationZ", QJsonValue(eigenTranslationZ_));

    json.insert("targetPointSize", QJsonValue(targetPointSize_));
    json.insert("targetPointColor", QJsonValue(targetPointColor_.name()));
    json.insert("outputPointSize", QJsonValue(outputPointSize_));
    json.insert("outputPointColor", QJsonValue(outputPointColor_.name()));

    json.insert("resultHasConverged", QJsonValue(resultHasConverged_));
    json.insert("resultFitnessScore", QJsonValue(resultFitnessScore_));

    return json;
}
